/**
 * 工程名称:OMSJobExecutor
 * 文件名称:SysRefundServiceImpl.java
 * 所属包:cn.rkylin.oms.sysrefund.servcie.impl
 * 创建时间:2017年9月21日下午2:55:49
 * 创建人:zhanghao
 */

package cn.rkylin.oms.sysrefund.servcie.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;

import cn.rkylin.apollo.common.util.DateUtils;
import cn.rkylin.apollo.common.util.HttpUtils;
import cn.rkylin.core.service.ApolloService;
import cn.rkylin.core.utils.StringUtil;
import cn.rkylin.oms.base.refundReasonType.domain.RdfundReasonType;
import cn.rkylin.oms.base.refundReasonType.service.RdfundReasonTypeService;
import cn.rkylin.oms.common.base.AbstractAdapterFactory;
import cn.rkylin.oms.common.consts.ECRefundStatusConsts;
import cn.rkylin.oms.common.consts.OrderOperStatusConsts;
import cn.rkylin.oms.common.consts.StatusConsts;
import cn.rkylin.oms.common.consts.StoreTypeConsts;
import cn.rkylin.oms.common.consts.SysRefundStatusConsts;
import cn.rkylin.oms.common.consts.YesNoConst;
import cn.rkylin.oms.common.utils.CodeUtil;
import cn.rkylin.oms.refund.adapter.RefundAdapter;
import cn.rkylin.oms.refund.adapter.RefundAdapterFactory;
import cn.rkylin.oms.refund.adapter.TaobaoRefundItemService;
import cn.rkylin.oms.refund.adapter.TaobaoRefundService;
import cn.rkylin.oms.refund.domain.EcRefund;
import cn.rkylin.oms.refund.domain.EcRefundItem;
import cn.rkylin.oms.refund.vo.EcRefundVO;
import cn.rkylin.oms.sysOrder.dao.ISysOrderDAO;
import cn.rkylin.oms.sysOrder.domain.SysOrder;
import cn.rkylin.oms.sysOrder.domain.SysOrderGoods;
import cn.rkylin.oms.sysOrder.service.ISysOrderService;
import cn.rkylin.oms.sysOrder.vo.SysOrderVO;
import cn.rkylin.oms.sysrefund.dao.ISysRefundDAO;
import cn.rkylin.oms.sysrefund.dao.ISysRefundSkuDAO;
import cn.rkylin.oms.sysrefund.domain.SysRefund;
import cn.rkylin.oms.sysrefund.domain.SysRefundSku;
import cn.rkylin.oms.sysrefund.servcie.ISysRefundService;
import cn.rkylin.oms.sysrefund.vo.SysRefundVO;
import cn.rkylin.oms.sysreturn.domain.SysReturn;
import cn.rkylin.oms.sysreturn.domain.SysReturnSku;
import cn.rkylin.oms.sysreturn.service.ISysReturnService;
import cn.rkylin.oms.sysreturn.vo.SysReturnVO;
import cn.rkylin.oms.system.logistics.domain.Logistics;
import cn.rkylin.oms.system.logistics.service.ILogisticsService;
import cn.rkylin.oms.system.logistics.vo.LogisticsVO;
import cn.rkylin.oms.system.project.vo.ProjectVO;
import cn.rkylin.oms.system.shop.service.IShopService;
import cn.rkylin.oms.system.shop.vo.ShopVO;
import cn.rkylin.oms.warehouse.shiporder.dao.ShiporderDAOImpl;
import cn.rkylin.oms.warehouseDocking.domain.Stor;
import cn.rkylin.oms.warehouseDocking.service.StorService;

/**
 * 类名:SysRefundServiceImpl <br/>
 * 作用: 系统退款单服务层实现. <br/>
 * 创建原因: 对系统退款单提供对外实现. <br/>
 * 创建时间: 2017年9月21日 下午2:55:49 <br/>
 *
 * @author zhanghao
 * @version v1.0
 */
@Service("sysRefundService")
public class SysRefundServiceImpl extends ApolloService implements ISysRefundService {
    private static final String RETURN_STATUS_WAIT_RECEIVE = "f";
	private static final Log logger = LogFactory.getLog(SysRefundServiceImpl.class);
    public static final String RETURN_FINISH_TYPE_EXCEPTION = "e";
    public static final String RETURN_STATUS_WAIT_AUTHEN = "a";
    public static final String RETURN_STATUS_WAIT_RECEIVE_GOODS = RETURN_STATUS_WAIT_RECEIVE;
    public static final String RETURN_STATUS_COMPLETE = "z";

    /**
     * taobaoRefundService:系统退款单服务层.
     */
    @Autowired
    TaobaoRefundService taobaoRefundService;
    /**
     * sysOrderService:平台订单服务层.
     */
    @Autowired
    ISysOrderService sysOrderService;
    /**
     * sysRefundDAO:系统退款单数据访问层.
     */
    @Autowired
    ISysRefundDAO sysRefundDAO;
    /**
     * sysRefundSkuDAO:系统退款单详情数据访问层.
     */
    @Autowired
    ISysRefundSkuDAO sysRefundSkuDAO;
    
    @Autowired
    ILogisticsService LgstService;
    
    /**
     * taobaoRefundItemService:平台退款单详情服务层.
     */
    @Autowired
    TaobaoRefundItemService taobaoRefundItemService;

    /**
     * sysReturnService:退款单服务层对象.
     */
    @Autowired
    ISysReturnService sysReturnService;
    /**
     * shopService:店铺服务层对象.
     */
    @Autowired
    IShopService shopService;

    /**
     * sysOrderDAO:系统订单数据访问对象.
     */
    @Autowired
    private ISysOrderDAO sysOrderDAO;

    @Autowired
    private RdfundReasonTypeService refundReasonTypeService;
    
    @Autowired
    private ShiporderDAOImpl shiporderDAOImpl;

    @Autowired
    private StorService storService;
    
    /**
     * OMS调用地址
     */
    @Value("${oms.address}")
    private String omsUrl;
    
    
    private Map<String,Map<String,Logistics>> lgstMap = null;

    /**
     * 平台退款单自动下载.<br/>
     * 1. 生成系统退款单及其明细 <br/>
     * 2. 如果平台退款单有退货需求，生成系统退货单及其明细 <br/>
     * 3. 锁定订单<br/>
     */
    @Override
    public Object downloadEcRefund(String shopId,boolean isFetching) throws Exception {
        if(isFetching){
            // TODO: 调用方法从淘宝平台下载退款单
        }
        Object returnObject = null;
        logger.debug("店铺[" + shopId + "]开始执行平台退款单进系统...");
        // 获取即将进系统的平台退款单列表：
        List<EcRefundVO> ecRefundVOList = getEcRefundListToLoad(shopId);

        downloadSysRefund(shopId, ecRefundVOList);
        return returnObject;
    }

    /**
     * downloadSysRefund:平台退款单进系统. <br/>
     *
     * @author zhanghao
     * @param shopId
     * @param ecRefundVOList
     * @throws Exception
     */
    private void downloadSysRefund(String shopId, List<EcRefundVO> ecRefundVOList) throws Exception {
        if (ecRefundVOList.size() > 0) {
            boolean isAutoAfterSale = isAutoAfterSaleOpen(shopId); // 是否开启自动售后
            boolean isAutoGenerateReturn = isAutoGenerateReturn(shopId); // 是否自动创建退货单

            if (isAutoAfterSale && !isAutoGenerateReturn) {
                // 不创建退货单且不判断锁定订单
                createSysRefund(ecRefundVOList);
            } else if (isAutoAfterSale && isAutoGenerateReturn) {
                // 创建退货单且不判断是否锁定订单
                createSysRefundWithReturn(ecRefundVOList);
            } else if (!isAutoAfterSale && isAutoGenerateReturn) {
                // 创建退货单且判断是否锁定订单
                createSysRefundWithReturnAndLockOrder(ecRefundVOList);
            } else {
                // 不创建退货单且判断是否锁定订单
                createSysRefundWithLockOrder(ecRefundVOList);
            }

            logger.debug("店铺[" + shopId + "]平台退款单进系统执行完成...");
        } else {
            logger.debug("店铺[" + shopId + "]本次未找到平台退款单...");
        }
    }

    /**
     * 退款单状态更新.
     * 
     * @see cn.rkylin.oms.sysrefund.servcie.ISysRefundService#updateEcRefund(java.lang.String,boolean)
     */
    @Override
    public Map<String,Object> updateEcRefund(String shopId,boolean isFetching) throws Exception {
        updateEcRefund(shopId,"","");
        return getSuccessMap("店铺[" + shopId + "]执行退款单更新完成");
    }

    /**
     * 退款单状态更新.
     */
    private void updateEcRefund(String shopId,String ecRefundCode,String buyerNick) throws Exception {
        logger.debug("店铺[" + shopId + "]开始执行退款单更新");
        // 获取待更新退款单列表
        List<SysRefundVO> sysRefundVOList = getSysRefundListToUpdate(shopId,ecRefundCode,buyerNick);
        logger.debug("有"+sysRefundVOList.size()+"条退款单即将更新");
        if (sysRefundVOList.size() > 0) {
            updateRefundBatch(sysRefundVOList);
            // 更新最后执行时间
            ShopVO shopUpdate = new ShopVO();
            shopUpdate.setShopId(shopId);
            shopUpdate.setRefundLastUpdateTime(new Date());
            shopService.update(shopUpdate);
            logger.debug("店铺[" + shopId + "]执行退款单更新完成");
        } else {
            logger.debug("店铺[" + shopId + "]本次未找到可用于更新的退款单列表");
        }
        
    }
    
    /**
     * 根据店铺ID和平台退款单号执行系统退款单手动生成任务，具体逻辑为：<br/>
     * 1. 调用平台退款单下载功能下载平台退款单；<br/>
     * 2. 根据该平台退款单号获取可进系统的平台退款单列表<br/>
     * 3. 如果列表大于0，则执行进系统操作；如果列表等于0，则执行更新操作 <br/>
     *
     * @throws Exception
     * @see cn.rkylin.oms.sysrefund.servcie.ISysRefundService#downloadEcRefundByEcRefundCode(java.lang.String,
     *      java.lang.String,boolean)
     */
    @Override
    public Map<String, Object> downloadEcRefundByEcRefundCode(String shopId, String ecRefundCode,boolean isFetching) throws Exception {
        Map<String, Object> returnMap = new HashMap<String,Object>();
        if(isFetching){
            // 1. 执行下载平台退款单
            RefundAdapter refundAdapter = RefundAdapterFactory.getRefundAdapter(shopId);
            Map<String, Object> paramMap = new HashMap<String,Object>();
            paramMap.put("refundId",ecRefundCode);
            refundAdapter.download(shopId,paramMap);
        }
        // 2. 获取可下载的系统退款单
        List<EcRefundVO> ecRefundVOList = getEcRefundListToLoad(shopId, ecRefundCode, "");
        logger.debug("有"+ecRefundVOList.size()+"条退款单即将进系统");
        
        if (ecRefundVOList.size() > 0) {
            logger.debug("平台退款单[" + ecRefundCode + "]开始执行平台退款单进系统...");
            downloadSysRefund(shopId, ecRefundVOList);
            logger.debug("平台退款单[" + ecRefundCode + "]执行平台退款单进系统完成");
        }
        
        logger.debug("平台退款单[" + ecRefundCode + "]开始执行平台退款单更新...");
        updateEcRefund(shopId, "","");
        logger.debug("平台退款单[" + ecRefundCode + "]执行平台退款单更新完成");

        return returnMap;
    }

    /**
     * 根据店铺ID和客户ID执行平台退款单进系统
     * @throws Exception
     * @see cn.rkylin.oms.sysrefund.servcie.ISysRefundService#downloadEcRefundByBuyerNick(java.lang.String,
     *      java.lang.String,boolean)
     */
    @Override
    public Map<String, Object> downloadEcRefundByBuyerNick(String shopId, String buyerNick,boolean isFetching) throws Exception {
        Map<String, Object> returnMap = new HashMap<String,Object>();
        if(isFetching){
            // 1. 执行下载平台退款单
            RefundAdapter refundAdapter = RefundAdapterFactory.getRefundAdapter(shopId);
            Map<String, Object> paramMap = new HashMap<String,Object>();
            paramMap.put("buyerNick",buyerNick);
            refundAdapter.download(shopId,paramMap);
        }
        // 2. 获取可下载的系统退款单
        List<EcRefundVO> ecRefundVOList = getEcRefundListToLoad(shopId, "", buyerNick);
        if (ecRefundVOList.size() > 0) {
            logger.debug("用户[" + buyerNick + "]开始执行平台退款单进系统...");
            downloadSysRefund(shopId, ecRefundVOList);
            logger.debug("用户[" + buyerNick + "]执行平台退款单进系统完成");
        }
        // 3. 执行更新退款单任务
        logger.debug("用户[" + buyerNick + "]开始执行平台退款单更新...");
        updateEcRefund(shopId, "","");
        logger.debug("用户[" + buyerNick + "]执行平台退款单更新完成");

        return returnMap;
    }

    /**
     * createSysRefundWithReturnAndLockOrder:判断是否创建退货单和是否锁定订单. <br/>
     *
     * @author zhanghao
     * @param ecRefundVOList
     * @throws Exception
     */
    private boolean createSysRefundWithReturnAndLockOrder(List<EcRefundVO> ecRefundVOList) throws Exception {
        boolean returnValue = false;
        SysOrder tempOrder = null;
        Map<String, Map<String, SysOrderGoods>> orderItemMap = new HashMap<String, Map<String, SysOrderGoods>>(); // 缓存订单信息
        for (EcRefundVO ecRefund : ecRefundVOList) {
            // 根据平台退款单对象生成系统退款单对象
            SysRefundVO sysRefund = generateSysRefundFromEcRefund(ecRefund);

            // 平台退款单对象相关的系统订单对象
            tempOrder = ecRefund.getOrder();
            String tempOrderId = tempOrder.getOrderId();
            boolean countingDeleted = false;
            if("c".equalsIgnoreCase(tempOrder.getCombStus())) {
                countingDeleted = true;
            }
            if (null != tempOrder) {
                try {
                    if (!orderItemMap.containsKey(tempOrderId)) {
                        prepareOrderMap(orderItemMap, tempOrderId,countingDeleted);
                    }
                    // 根据平台退款单和系统退款单信息生成系统退款单明细信息列表
                    boolean saveSuccess = saveSysRefund(ecRefund, sysRefund, orderItemMap);
                    // 锁定订单
                    if (saveSuccess&&null != tempOrder && isOrderLockAvailable(tempOrder)) {
                        lockOrder(tempOrder);
                    }
                    
                    // 生成退货单或者合并退货单
                    if (saveSuccess&&hasGenerateReturn(ecRefund, sysRefund,orderItemMap)) {
                        logger.debug(String.format("即将为系统退款单[编号：%s]生成系统退货单", ecRefund.getEcRefundCode()));
                        generateSysReturn(ecRefund, sysRefund, orderItemMap);
                    }
                } catch (Exception e) {
                    logger.error(String.format("平台退款单(单号：%s)自动下载失败，已跳过自动下载！", ecRefund.getEcRefundCode()));
                }
            }
            continue;
        }
        return returnValue;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void prepareOrderMap(Map<String, Map<String, SysOrderGoods>> orderItemMap, String orderId,boolean countingDeleted) throws Exception {
        Map<String, SysOrderGoods> itemMap = new HashMap<String, SysOrderGoods>();
        Map tempQueryMap = new HashMap();
        List orderIdList = new ArrayList<String>();
        orderIdList.add(orderId);
        tempQueryMap.put("order_id", orderIdList);
        tempQueryMap.put("countDelete", "y");

        List<SysOrderGoods> sysOrderGoodsList = sysOrderDAO.selectSysOrderGoodsList(tempQueryMap);
        if (sysOrderGoodsList.size() > 0) {
            for (SysOrderGoods sysOrderGoods : sysOrderGoodsList) {
                if(itemMap.containsKey(sysOrderGoods.getOid())){
                    sysOrderGoods.setComposeGoodsFlag(1);
                }

                if(StringUtils.isNotEmpty(sysOrderGoods.getOid())){
                    itemMap.put(sysOrderGoods.getOid(), sysOrderGoods); // 在生成系统退款单时，将根据平台商品oid找系统商品
                }else if(StringUtils.isEmpty(sysOrderGoods.getOid())&&YesNoConst.YES.equalsIgnoreCase(sysOrderGoods.getIsGift())){
                    itemMap.put(sysOrderGoods.getSkuCode(), sysOrderGoods); // 在生成系统退款单时，将根据平台商品oid找系统商品
                }
            }
        }
        // 添加合并前的的订单商品
        if(countingDeleted) {
            List<SysOrderGoods> sysDeletedOrderGoodsList = sysOrderDAO.selectDeletedSysOrderGoodsList(tempQueryMap);
            if (sysDeletedOrderGoodsList.size() > 0) {
                for (SysOrderGoods sysOrderGoods : sysDeletedOrderGoodsList) {
                    if(itemMap.containsKey(sysOrderGoods.getOid())){
                        sysOrderGoods.setComposeGoodsFlag(1);
                    }
                    itemMap.put(sysOrderGoods.getOid(), sysOrderGoods); // 在生成系统退款单时，将根据平台商品code找系统商品
                }
            }
        }
        orderItemMap.put(orderId, itemMap);
    }

    private boolean createSysRefund(List<EcRefundVO> ecRefundVOList) throws Exception {
        boolean returnValue = false;
        SysOrder tempOrder = null;
        Map<String, Map<String, SysOrderGoods>> orderItemMap = new HashMap<String, Map<String, SysOrderGoods>>();
        for (EcRefundVO ecRefund : ecRefundVOList) {
            // 根据平台退款单生成系统退款单
            SysRefundVO sysRefund = generateSysRefundFromEcRefund(ecRefund);
            tempOrder = ecRefund.getOrder();
            String tempOrderId = tempOrder.getOrderId();
            boolean countingDeleted = false;
            if("c".equalsIgnoreCase(tempOrder.getCombStus())) {
                countingDeleted = true;
            }
            if (null != tempOrder) {
                try {
                    if (!orderItemMap.containsKey(tempOrderId)) {
                        prepareOrderMap(orderItemMap, tempOrderId,countingDeleted);
                    }
                    saveSysRefund(ecRefund, sysRefund, orderItemMap);
                    logger.debug(String.format("平台退款单[编号：%s]及其明细进系统操作成功", ecRefund.getEcRefundCode()));
                } catch (Exception e) {
                    logger.error(String.format("平台退款单(单号：%s)自动下载失败，已跳过自动下载！", ecRefund.getEcRefundCode()));
                }
            }
            continue;
        }
        return returnValue;
    }

    private boolean createSysRefundWithLockOrder(List<EcRefundVO> ecRefundVOList) throws Exception {
        boolean returnValue = false;
        SysOrder tempOrder = null;
        Map<String, Map<String, SysOrderGoods>> orderItemMap = new HashMap<String, Map<String, SysOrderGoods>>();
        for (EcRefundVO ecRefund : ecRefundVOList) {
            // 根据平台退款单生成系统退款单
            SysRefundVO sysRefund = generateSysRefundFromEcRefund(ecRefund);
            tempOrder = ecRefund.getOrder();
            String tempOrderId = tempOrder.getOrderId();
            boolean countingDeleted = false;
            if("c".equalsIgnoreCase(tempOrder.getCombStus())) {
                countingDeleted = true;
            }
            if (null != tempOrder) {
                try {
                    if (!orderItemMap.containsKey(tempOrderId)) {
                        prepareOrderMap(orderItemMap, tempOrderId,countingDeleted);
                    }
                    // 根据平台退款单和系统退款单信息生成系统退款单明细信息列表
                    boolean saveSuccess = saveSysRefund(ecRefund, sysRefund, orderItemMap);
                    logger.debug(String.format("平台退款单[编号：%s]及其明细进系统操作成功", ecRefund.getEcRefundCode()));
                    // 锁定订单
                    if (null != tempOrder && isOrderLockAvailable(tempOrder)&&saveSuccess) {
                        lockOrder(tempOrder);
                    }
                } catch (Exception e) {
                    logger.error(String.format("平台退款单(单号：%s)自动下载失败，已跳过自动下载！", ecRefund.getEcRefundCode()));
                }
            }
            continue;
        }

        return returnValue;
    }

    private boolean createSysRefundWithReturn(List<EcRefundVO> ecRefundVOList) throws Exception {
        boolean returnValue = false;
        SysOrder tempOrder = null;
        Map<String, Map<String, SysOrderGoods>> orderItemMap = new HashMap<String, Map<String, SysOrderGoods>>();
        for (EcRefundVO ecRefund : ecRefundVOList) {
            // 根据平台退款单生成系统退款单
            SysRefundVO sysRefund = generateSysRefundFromEcRefund(ecRefund);
            tempOrder = ecRefund.getOrder();
            String tempOrderId = tempOrder.getOrderId();
            boolean countingDeleted = false;
            if("c".equalsIgnoreCase(tempOrder.getCombStus())) {
                countingDeleted = true;
            }
            if (null != tempOrder) {
                try {
                    if (!orderItemMap.containsKey(tempOrderId)) {
                        prepareOrderMap(orderItemMap, tempOrderId,countingDeleted);
                    }
                    // 根据平台退款单和系统退款单信息生成系统退款单明细信息列表
                    boolean saveSuccess = saveSysRefund(ecRefund, sysRefund, orderItemMap);
                    logger.debug(String.format("平台退款单[编号：%s]及其明细进系统操作成功", ecRefund.getEcRefundCode()));
                    // 生成退货单或者合并退货单
                    if (saveSuccess&&hasGenerateReturn(ecRefund, sysRefund, orderItemMap)) {
                        logger.debug(String.format("即将为系统退款单[编号：%s]生成系统退货单", ecRefund.getEcRefundCode()));
                        generateSysReturn(ecRefund, sysRefund, null);
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage());
                    logger.error(String.format("平台退款单(单号：%s)自动下载失败，已跳过自动下载！", ecRefund.getEcRefundCode()));
                }
            }
            continue;
        }

        return returnValue;
    }

    /**
     * saveSysRefund:保存平台退款单<br/>
     * 获取平台退款单明细并生成系统退款单明细，并保存系统退款单和系统退款单明细.<br/>
     *
     * @author zhanghao
     * @param ecRefund 平台退款单对象
     * @param sysRefund 系统退款单对象
     * @param orderItemMap  订单商品Map对象
     * @throws Exception    抛出异常
     */
    private boolean saveSysRefund(EcRefundVO ecRefund, SysRefundVO sysRefund, Map<String, Map<String, SysOrderGoods>> orderItemMap)
            throws Exception {
        boolean returnValue = false;
        // 根据平台退款单和系统退款单信息生成系统退款单明细信息列表
        List<SysRefundSku> tempSysRefundSkuList = generateSysRefundSkuListFromEcRefund(ecRefund, sysRefund, orderItemMap);
        if(tempSysRefundSkuList.size()>0){
            sysRefund.setSysRefundSkuList(tempSysRefundSkuList);
            int iRes = sysRefundDAO.insertSelective(sysRefund);
            if (iRes > 0){
                //更新系统订单退款单的状态
                SysOrderVO orderVOUpdate = new SysOrderVO();
                orderVOUpdate.setOrderId(sysRefund.getOrderId());
                orderVOUpdate.setHasRefund("y");
                int iOrderUpdate = sysOrderDAO.updateByPrimaryKeySelectiveSysOrder(orderVOUpdate);
            }
            for (SysRefundSku sysRefundSku : tempSysRefundSkuList) {
                sysRefundSkuDAO.insertSelective(sysRefundSku);
            }
            // 更新平台退款单状态为已插入
            taobaoRefundService.updateEcRefundInsertStatus(ecRefund);
            returnValue = true;
        }

        return returnValue;
    }

    /**
     * generateSysReturn:生成系统退货单. <br/>
     *
     * @author zhanghao
     * @param ecRefund
     * @param sysRefund
     * @param orderItemMap
     * @throws Exception
     */
    private void generateSysReturn(EcRefundVO ecRefund, SysRefundVO sysRefund, Map<String, Map<String, SysOrderGoods>> orderItemMap)
            throws Exception {
        // 根据平台退款单、系统退款单信息生成系统退货单
        SysReturnVO sysReturn = generateReturn(ecRefund, sysRefund);
        // 根据平台退款单、系统退款单信息和系统退货单信息生成退货单明细信息
        List<SysReturnSku> tempSysReturnGoodsList = generateReturnSkuList(ecRefund, sysRefund, sysReturn,orderItemMap);
        sysReturn.setSysReturnSku(tempSysReturnGoodsList);
        sysReturnService.generateReturn(sysReturn);

        // 更新平台退款单的退货单插入状态
        taobaoRefundService.updateReturnInsertStatus(ecRefund);
    }

    /**
     * lockOrder:锁定一条订单. <br/>
     *
     * @author zhanghao
     * @param order
     * @return
     * @throws Exception 
     */
    private boolean lockOrder(SysOrder order) throws Exception {
        boolean lockOrder = false;
        SysOrderVO updateOrderParam = new SysOrderVO();
        updateOrderParam.setOrderId(order.getOrderId());
        updateOrderParam.setOrderCode(order.getOrderCode());

        updateOrderParam.setUpdateTime(new Date());
        updateOrderParam.setIsLock(YesNoConst.YES);
        updateOrderParam.setOperStus(OrderOperStatusConsts.LOCK);
        updateOrderParam.setLockRemark("系统自动锁定订单");
        updateOrderParam.setLockTime(new Date());
        updateOrderParam.setLockUserName("SYSTEM");
        try {
            sysOrderService.updateLockOrder(updateOrderParam);
            lockOrder = true;
            logger.debug(String.format("订单[单号：%s]锁定成功", order.getOrderCode()));
        } catch (Exception e) {
            logger.debug(String.format("订单[单号：%s]锁定失败", order.getOrderCode()));
            lockOrder = false;
        }
        
        if(lockOrder) {
            // 取消或者申请取消发货单
            lockShipOrder(order);
        }
        return lockOrder;
    }
    
    @Value("${oms.address}")
    private String omsAddres;

    /**
     * lockShipOrder:锁定发货单. <br/>
     *
     * @author zhanghao
     * @param order
     * @throws Exception 
     */
    @Override
    public Map<String, String> lockShipOrder(SysOrder order) throws Exception {
        // 请求地址
        String requestUrl = omsAddres + "shiporder/lockForSysRefund.action";
        
        String requestParams = "orderId="+order.getOrderId();
        // 请求数据
        String resJson = HttpUtils.sendByGet(requestUrl, requestParams );
        // 转换响应数据
        Map<String, String> resultMap = JSON.parseObject(resJson, Map.class);
        if("success".equalsIgnoreCase(resultMap.get("result"))){
            logger.debug("订单["+order.getOrderCode()+"]相关发货单锁定成功");
        }else {
            logger.error("订单["+order.getOrderCode()+"]相关发货单锁定失败:"+resultMap.get("msg"));
        }
        return resultMap;
    }

    /**
     * isOrderLockAvailable:订单是否可以锁定. <br/>
     *
     * @author zhanghao
     * @param order
     * @return
     */
    private boolean isOrderLockAvailable(SysOrder order) {
        boolean returnValue = false;
        String[] compareArray = { "a", "i", "k" };
        if (!OrderOperStatusConsts.LOCK.equalsIgnoreCase(order.getOperStus())
                && ("n".equalsIgnoreCase(order.getCombStus()) || "c".equalsIgnoreCase(order.getCombStus()))
                && StringUtils.isEmpty(order.getForderId()) && YesNoConst.NO.equalsIgnoreCase(order.getIsCancel())
                && Arrays.asList(compareArray).contains(order.getOrderStatus())) {
            returnValue = true;
        }
        return returnValue;
    }

    /**
     * getEcRefundListToUpdate:获取待更新的平台退款单列表. <br/>
     *
     * @author zhanghao
     * @param shopId
     * @param ecRefundCode
     * @param buyerNick
     * @return
     */
    private List<SysRefundVO> getSysRefundListToUpdate(String shopId,String ecRefundCode,String buyerNick) throws Exception {
        List<SysRefundVO> returnValue = new ArrayList<SysRefundVO>();
        SysRefundVO sysRefundVO = new SysRefundVO();
        sysRefundVO.setShopId(shopId);

        // 手动更新选项，增加平台退款单号和用户昵称作为查询条件 - 开始
        sysRefundVO.setEcRefundCode(ecRefundCode);
        sysRefundVO.setBuyerNick(buyerNick);
        // 手动更新选项，增加平台退款单号和用户昵称作为查询条件 - 结束

        ShopVO shop = AbstractAdapterFactory.getShop(shopId);
        Date sysRefundLastUpdateTime = shop.getRefundLastUpdateTime();
        sysRefundVO.setSysRefundLastUpdateTime(sysRefundLastUpdateTime);
        returnValue = sysRefundDAO.selectBySelectiveKey4Update(sysRefundVO);
        return returnValue;
    }

    /**
     * getEcRefundListToLoad:获取待下载的平台退款单列表. <br/>
     *
     * @author zhanghao
     * @param shopId
     * @return
     */
    private List<EcRefundVO> getEcRefundListToLoad(String shopId) throws Exception {
        return getEcRefundListToLoad(shopId, "", "");
    }

    /**
     * updateRefund:批量执行退款单更新. <br/>
     *
     * @author zhanghao
     * @param sysRefundVOList
     */
    private void updateRefundBatch(List<SysRefundVO> sysRefundVOList) {
        for (SysRefundVO sysRefundVO : sysRefundVOList) {
            // 判断退款单是否有已归档的订单，如果有，取消归档
            if (hasArchiveOrder(sysRefundVO)) {
                cancelArchiveOrder(sysRefundVO.getOrder());
            }
            try {
                // 退款单下载状态变化后的相关业务操作
                updateRefundStatus(sysRefundVO);
            } catch (Exception e) {
                logger.error(e.getMessage());
                continue; // 继续下一条更新
            }
        }
    }

    /**
     * updateRefundStatus:退款单状态变化后的相关业务操作. <br/>
     *
     * @author zhanghao
     * @throws Exception
     */
    private void updateRefundStatus(SysRefundVO sysRefundVOParam) throws Exception {
        // （跳过）更新退款单上次退款状态

        // （跳过）更新退款单最新退款状态
        
        // 更新平台退款原因、货物状态、买家是否退货等信息 + 退款超时时间，更新
        SysRefundVO sysRefundVO = UpdateRefundOtherInfo(sysRefundVOParam);
        
        // （跳过）平台退款单的状态由拒绝变为申请退款时，清空拒绝人等信息

        // 如果物流公司和物流单号不为空，则更新物流公司和物流单号
        if (StringUtils.isNotEmpty(sysRefundVO.getLgstName().concat(sysRefundVO.getLgstNo()))) {
            UpdateRtrnExchLgst(sysRefundVO);
        }

        // 更新平台退款单是否有退货 差异标识
        if (sysRefundVO.getEcRefundStatus().equalsIgnoreCase("WAIT_SELLER_AGREE")
                || sysRefundVO.getEcRefundStatus().equalsIgnoreCase("WAIT_BUYER_RETURN_GOODS")
                || sysRefundVO.getEcRefundStatus().equalsIgnoreCase("WAIT_SELLER_CONFIRM_GOODS")) {
            UpdateRefundDiff(sysRefundVO);
        }

        // 退款单自动更新时，先不做退货单状态更新了
        if (sysRefundVO.getRefundStatus().equalsIgnoreCase(SysRefundStatusConsts.CLOSED)) {
            logger.debug("由于退款单关闭："+sysRefundVO.getRefundStatus()+"即将执行废弃退货单。");
            // 退款单变为关闭时，异常完成相应的退货单
            UpdateRtrnExchCancelYn(sysRefundVO);
        }
    }

    /**
     * UpdateRtrnExchCancelYn:异常完成相应的退货单 <br/>
     *
     * @author zhanghao
     * @param sysRefundVO
     * @throws Exception
     */
    private void UpdateRtrnExchCancelYn(SysRefundVO sysRefundVO) throws Exception {
        // 根据退款单关联的订单信息，获取退货单信息
        /*SysReturnVO queryParam = new SysReturnVO();
        queryParam.setSourceType("or");
        queryParam.setSourceId(sysRefundVO.getOrderId());
        queryParam.setIsAutoCreate(YesNoConst.YES);*/
        List<SysReturnVO> returnList = sysReturnService.querySysReturnVOByRefundId(sysRefundVO.getRefundId());
        for (SysReturnVO sysReturnVO : returnList) {
            closeSysReturnSingle(sysReturnVO,sysRefundVO);
        }
    }

    /**
     * closeSysReturn:废弃当前退货单. <br/>
     *
     * @author zhanghao
     * @param sysReturnVO
     * @param sysRefundVO
     * @throws Exception
     */
    private int closeSysReturnSingle(SysReturnVO sysReturnVO, SysRefundVO sysRefundVO) throws Exception {
        int returnValue = 0;
        
        /*
         *  有下列情况之一，不执行关闭退货单：
         *  1. 非自动生成的退货单
         *  2. 已取消的退货单
         *  3. 已完成的退货单
         *  4. 待发货状态的退货单
         *  （上述情况不作任何操作）
         *  5. 退货单商品在扣除退款单商品后，还剩余非赠品的商品
         *  （上述情况将删除退货单上的退款商品）
         */
        if(YesNoConst.NO.equalsIgnoreCase(sysReturnVO.getIsAutoCreate())
                || YesNoConst.YES.equalsIgnoreCase(sysReturnVO.getIsCancel())
                || RETURN_STATUS_COMPLETE.equalsIgnoreCase(sysReturnVO.getReturnStatus())
                || RETURN_STATUS_WAIT_RECEIVE.equalsIgnoreCase(sysReturnVO.getReturnStatus())
                ){
            return returnValue;
        }
        
        /*
         * 下列情况全部满足，直接关闭退货单：
         * 1. 自动生成的退货单
         * 2. 退货单未取消
         * 3. 待审核的退货单
         */

        // 根据项目ID获取项目库存类型：ext或者local
        String storType = getStoreTypeFromProject();
        if (StoreTypeConsts.EXT.equalsIgnoreCase(storType)) {
            if (sysReturnVO.getSysReturnSku().size() <= 1) {
                returnValue = cancelReturnSingleExternal(sysReturnVO);
            } else if (sysReturnVO.getSysReturnSku().size() > 1) {
                returnValue = cancelReturnMultiExternal(sysReturnVO,sysRefundVO);
            }
        } else if (StoreTypeConsts.LOCAL.equalsIgnoreCase(storType)) {
            // 本地仓库的情况不考虑
            if (sysReturnVO.getSysReturnSku().size() <= 1) {
                returnValue = cancelReturnSingleLocal(sysReturnVO);
            } else if (sysReturnVO.getSysReturnSku().size() > 1) {
                returnValue = cancelReturnMultiLocal(sysReturnVO);
            }
        }

        return returnValue;

    }

    private boolean hasUnPresentSku(List<SysReturnSku> returnSkuList) {
        boolean returnValue = false;
        for(SysReturnSku returnSku :returnSkuList){
            if(YesNoConst.NO.equalsIgnoreCase(returnSku.getIsGift())){
                returnValue = true;
                break;
            }
        }
        return returnValue;
    }

    /**
     * cancelReturnMultiLocal:废弃退货单（多条、本地仓）. <br/>
     *
     * @author zhanghao
     * @param sysReturnVO
     */
    private int cancelReturnMultiLocal(SysReturnVO sysReturnVO) {
        // 暂时不考虑本地仓的情况
        return 0;

    }

    /**
     * cancelReturnMultiExternal:废弃退货单（多条、三方仓）. <br/>
     *
     * @author zhanghao
     * @param sysReturnVO
     * @param sysRefundVO
     * @throws Exception
     */
    private int cancelReturnMultiExternal(SysReturnVO sysReturnVO, SysRefundVO sysRefundVO) throws Exception {
        int returnValue = 0;

        List<SysReturnSku> returnSkuList = sysReturnVO.getSysReturnSku();
        List<SysRefundSku> refundSkuList = sysRefundVO.getSysRefundSkuList();
        
        if(null==refundSkuList) {
        		refundSkuList = sysRefundSkuDAO.selectByRefundId(sysRefundVO.getRefundId());
        		sysRefundVO.setSysRefundSkuList(refundSkuList);
        }

        Set<String> removeReturnSkuSet=  new HashSet<String>();

        for(SysRefundSku sysRefundSku:refundSkuList){
            for(int i=0,j=returnSkuList.size();i<j;i++){
                SysReturnSku returnSku = returnSkuList.get(i);
                if(sysRefundSku.getRefundSkuId().equals(returnSku.getRefundSkuId())){
                    removeReturnSkuSet.add(returnSku.getReturnSkuId());
                    returnSkuList.remove(i);
                    break;
                }
            }
        }

        if(removeReturnSkuSet.size()>0&&hasUnPresentSku(returnSkuList)){
            // 如果退货单上包含非退款单商品，则删除退货单上的商品
            returnValue = sysReturnService.deleteReturnSkuByIdList(removeReturnSkuSet);

            /*if (returnValue >= 0) {
                // 设置退货单的状态为待审核
                SysReturnVO param = new SysReturnVO();
                param.setReturnId(sysReturnVO.getReturnId());
                param.setReturnStatus(StatusConsts.AWAIT);
                param.setUpdateTime(new Date());
                returnValue = sysReturnService.updateUnApproveSysReturn(param);
            }*/
        }else{
            // 直接废弃退货单
            cancelReturnSingleExternal(sysReturnVO);
        }

        return returnValue;
    }

    /**
     * cancelReturnSingleLocal:废弃退货单（单条、本地仓）. <br/>
     *
     * @author zhanghao
     * @param sysReturnVO
     * @throws Exception
     */
    private int cancelReturnSingleLocal(SysReturnVO sysReturnVO) throws Exception {
        // 暂时不考虑本地情况
        return 0;

    }

    /**
     * cancelReturnSingleExternal:废弃退货单（单条，第三方仓）. <br/>
     *
     * @author zhanghao
     * @param sysReturnVO
     * @throws Exception
     */
    private int cancelReturnSingleExternal(SysReturnVO sysReturnVO) throws Exception {
        // 处理单条退货商品的退货单
        SysReturnVO param = new SysReturnVO();
        param.setReturnId(sysReturnVO.getReturnId());
        param.setReturnStatus(StatusConsts.CANCEL);
        param.setUpdateTime(new Date());
        return sysReturnService.cancelSysReturn4Ext(param);
    }

    /**
     * getStoreTypeFromProject:根据项目ID获取当前仓库的库存类型. <br/>
     *
     * @author zhanghao
     * @return
     */
    private String getStoreTypeFromProject() {
        // 只考虑第三方库存类型
        return StoreTypeConsts.EXT;
    }

    /**
     * UpdateRefundDiff:更新是否有退货的标识. <br/>
     *
     * @author zhanghao
     * @param sysRefundVO
     */
    private void UpdateRefundDiff(SysRefundVO sysRefundVO) throws Exception {
        logger.debug("开始更新退款单的退货标识");
        SysRefundVO param = new SysRefundVO();
        List<EcRefund> ecRefundList = sysRefundVO.getEcRefunds();
        param.setHasGoodReturn(sysRefundVO.getEcRefunds().get(ecRefundList.size() - 1).getHasGoodReturn());
        param.setRefundId(sysRefundVO.getRefundId());
        try {
            EcRefundVO ecRefundVO = new EcRefundVO();
            ecRefundVO.setHasGoodReturn(sysRefundVO.getEcRefunds().get(ecRefundList.size() - 1).getHasGoodReturn());
            ecRefundVO.setEcRefundCode(sysRefundVO.getEcRefundCode());
            taobaoRefundService.updateReturnInsertStatus(ecRefundVO);
        } catch (Exception e) {
            logger.error("退款单[" + sysRefundVO.getRefundCode() + "]的退货标识更新失败");
            throw e;
        }
        logger.debug("退款单[" + sysRefundVO.getRefundCode() + "]的退货标识更新成功");
    }

    /**
     * UpdateRtrnExchLgst:更新退货单物流公司和物流单号等信息. <br/>
     *
     * @author zhanghao
     * @param sysRefundVO
     * @throws Exception
     */
    @SuppressWarnings("finally")
    private void UpdateRtrnExchLgst(SysRefundVO sysRefundVO) throws Exception {
        logger.debug("开始更新退货单的物流公司和物流单号");
        SysReturnVO sysReturnVO = new SysReturnVO();
        sysReturnVO.setSourceId(sysRefundVO.getOrderId());
        sysReturnVO.setReturnStatus("a"); // 状态为待审核
        sysReturnVO.setSourceType("or"); // 类型为订单
        
        List<SysReturnVO> returnList = sysReturnService.querySysReturnVOByRefundId(sysRefundVO.getRefundId());
        // 获取退款单关联的退货单
        
        for (SysReturn sysReturn : returnList) {
            try {
                // 如果退货单上物流公司或者快递单号是空，则更新物流公司和物流单号信息
                if(StringUtils.isEmpty(sysReturn.getLgstNo())||StringUtils.isEmpty(sysReturn.getLgstName())){
                    SysReturnVO param = new SysReturnVO();
                    LogisticsVO lgstInfo = getLgstInfoByName(sysRefundVO.getLgstName(),sysRefundVO.getPrjId());// 是否设置物流信息
                    if(null!=lgstInfo) {
                        param.setReturnId(sysReturn.getReturnId());
                        param.setLgstName(lgstInfo.getLgstName());
                        param.setLgstCode(lgstInfo.getLgstCode());
                        param.setLgstId(lgstInfo.getLgstId());
                        param.setLgstNo(sysRefundVO.getLgstNo());
                    }
                    sysReturnService.updateSysReturn(param);
                }
                logger.debug("更新退货单[" + sysReturn.getReturnCode() + "]的物流公司和物流单号完成");
            } catch (Exception e) {
                logger.error("更新退货单[" + sysReturn.getReturnCode() + "]的物流公司和物流单号失败");
            } finally{
                continue;
            }
        }
        logger.debug("更新退货单的物流公司和物流单号操作完成");
    }

    /**
     * UpdateRefundOtherInfo:更新退款单其它信息. <br/>
     * 更新平台退款原因、货物状态、买家是否退货、退款超时时间<br/>
     *
     * @author zhanghao
     * @param sysRefundVO
     * @throws Exception
     */
    private SysRefundVO UpdateRefundOtherInfo(SysRefundVO sysRefundVOParam) throws Exception {
        SysRefundVO sysRefundVO = sysRefundVOParam;
        List<EcRefund> ecRefundsList = sysRefundVO.getEcRefunds();
        EcRefund lastEcRefund = ecRefundsList.get(ecRefundsList.size() - 1);
        SysRefundVO record = new SysRefundVO();
        record.setRefundId(sysRefundVO.getRefundId());
        record.setEcRefundStatus(lastEcRefund.getRefundStatus());
        record.setRefundReason(lastEcRefund.getRefundReason());
        

        if (StringUtils.isNotEmpty(lastEcRefund.getRefundReason())) {
            try {
                RdfundReasonType refundReasonType = getRefundReasonByEcRefundReason(lastEcRefund.getRefundReason());
                record.setRefundReasonId(refundReasonType.getRefundReasonId());
                record.setRefundReasonName(refundReasonType.getRefundReasonName());
            } catch (Exception e) {
                logger.debug("未找到平台退款原因相关的系统退款原因，退款原因编号和名称将留空");
                record.setRefundReasonId("");
                record.setRefundReasonName("");
            }
        } else {
            record.setRefundReasonId("");
            record.setRefundReasonName("");
        }

        record.setBuyerRemark(lastEcRefund.getRefundDesc());
        record.setHasGoodReturn(lastEcRefund.getHasGoodReturn());
        record.setRefundFee(lastEcRefund.getRefundFee());
        record.setGoodStus(StringUtils.isEmpty(lastEcRefund.getEcTradeStus()) ? "BUYER_RECEIVED" : lastEcRefund.getEcTradeStus());
        record.setHasGoodReturn(lastEcRefund.getHasGoodReturn());
        record.setLgstName(lastEcRefund.getLgstName());
        record.setLgstNo(lastEcRefund.getLgstNo());
        record.setRefundTimeout(lastEcRefund.getRefundTimeout());

        String strRefundStatus = sysRefundVO.getRefundStatus();
        updateRefundInfoByStatus(record,lastEcRefund,strRefundStatus);
        
        int iRes = sysRefundDAO.updateByPrimaryKeySelective(record);
        if (iRes > 0 && "y".equals(record.getIsCancel())){

//wangxing add begin-------------------------------------------------------------------------
            //更新系统订单退款单的状态
            SysOrderVO orderVOUpdate = new SysOrderVO();
            //通过退款单id获取订单id
            SysRefund sysRefundForOne = sysRefundDAO.selectByPrimaryKey(record.getRefundId());
            if (sysRefundForOne != null) {
                String strSourceId = sysRefundForOne.getOrderId();
                if(org.apache.commons.lang.StringUtils.isNotBlank(strSourceId)){
                    //通过来源id获取未废弃退款单信息
                    List<SysRefund> SysRefundByOrderID = sysRefundDAO.selectSysRefundByOrderID(strSourceId);
                    if (SysRefundByOrderID == null || SysRefundByOrderID.size()<=0){
                        //没有 未废弃的退款单，更新订单退款单标识为 n
                        orderVOUpdate.setOrderId(strSourceId);
                        orderVOUpdate.setHasRefund("n");
                        int iOrderUpdate = sysOrderDAO.updateByPrimaryKeySelectiveSysOrder(orderVOUpdate);
                    }
                }
            }
//wangxing add end---------------------------------------------------------------------------


        }
        BeanUtils.copyProperties(record, sysRefundVO ,getNullPropertyNames(record));
        return sysRefundVO;
    }

    /**
     * updateRefundInfoByStatus:更新退款单相关信息. <br/>
     *
     * @author zhanghao
     * @param record
     * @param lastEcRefund
     */
    private void updateRefundInfoByStatus(SysRefundVO record, EcRefund lastEcRefund,String strRefundStatus) {
        Date now = new Date();
//        String returnString = SysRefundStatusConsts.REGISTER;    //wangxing 屏蔽
        String returnString = "";
        String ecRefundStatus = lastEcRefund.getRefundStatus();
        if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_WAIT_SELLER_AGREE)){
            if(YesNoConst.YES.equalsIgnoreCase(lastEcRefund.getHasGoodReturn())) {
                returnString = SysRefundStatusConsts.REFUND_APPLIED;
            }else {
                returnString = SysRefundStatusConsts.REGISTER;
            }
        }else if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_WAIT_BUYER_RETURN_GOODS)) {
            returnString = SysRefundStatusConsts.WAIT_BUYER_OPER;
            record.setRefundTimeout(null);
        }else if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_WAIT_SELLER_CONFIRM_GOODS)) {
            if ("d".equals(strRefundStatus) || "b".equals(strRefundStatus )||StringUtils.isEmpty(strRefundStatus)){
                returnString = SysRefundStatusConsts.REGISTER;
            }
        }else if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_SUCCESS)){
            returnString = SysRefundStatusConsts.REFUNDED;
            record.setRefundTimeout(null);
            record.setRefundTime(now);
        }else if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_SELLER_REFUSE_BUYER)){
            returnString = SysRefundStatusConsts.WAIT_BUYER_OPER;
            record.setRejectTime(now);
            record.setRefundTimeout(null);
        }
        else{
            returnString = SysRefundStatusConsts.CLOSED;
            record.setCloseTime(now);
            record.setIsCancel(YesNoConst.YES);
            record.setRefundTimeout(null);
        }

        if(StringUtils.isNotBlank(returnString)) {
            record.setRefundStatus(returnString);
        }
    }

    /**
     * cancelArchiveOrder:取消已归档的订单. <br/>
     *
     * @author zhanghao
     * @param order
     */
    private void cancelArchiveOrder(SysOrder order) {
        // 不考虑订单已归档的情况
    }

    /**
     * hasArchiveOrder:判断退款单是否有已归档的订单. <br/>
     *
     * @author zhanghao
     * @param sysRefundVO
     * @return
     */
    private boolean hasArchiveOrder(SysRefundVO sysRefundVO) {
        // 不考虑订单已归档的情况
        return false;
    }

    /**
     * isAutoAfterSaleOpen:判断系统是否开启自动售后. <br/>
     *
     * @author zhanghao
     * @param shopId
     * @return
     */
    private boolean isAutoAfterSaleOpen(String shopId) {
        boolean returnValue = false;
        try {
            ShopVO shopVO = shopService.findById(shopId);
            if (YesNoConst.YES.equals(shopVO.getIsAutoAfterSale())) {
                returnValue = true;
            } else {
                returnValue = false;
            }
        } catch (Exception e) {
            logger.error("获取店铺信息失败，未取得店铺自动开启售后的标识，将不开启自动售后");
        }
        return false;
    }

    /**
     * generateReturn:根据平台退款单和系统退款单，生成系统退货单对象. <br/>
     * 
     * @author zhanghao
     * @param ecRefund
     *            平台退款单对象
     * @param sysRefund
     *            系统退款单对象，包含退款单明细信息
     * @throws Exception
     */
    private SysReturnVO generateReturn(EcRefundVO ecRefund, SysRefundVO sysRefund) throws Exception {
        Date now = new Date();
        SysReturnVO sysReturnVO = new SysReturnVO();

        SysReturn componseReturnObj = getComposeSysReturn(sysRefund.getOrderId());
        if(null!=componseReturnObj){
            sysReturnVO.setReturnId(componseReturnObj.getReturnId());
            sysReturnVO.setReturnStatus(RETURN_STATUS_WAIT_AUTHEN);
            sysReturnVO.setUpdateTime(now);
        }else{
            BeanUtils.copyProperties(ecRefund.getOrder(), sysReturnVO);
            BeanUtils.copyProperties(ecRefund, sysReturnVO);
            BeanUtils.copyProperties(sysRefund, sysReturnVO);

            sysReturnVO.setFinishTime(null);


            sysReturnVO.setReturnId(getUUID());
            sysReturnVO.setReturnCode(generateReturnCode(ecRefund.getShopId()));
            sysReturnVO.setSourceId(ecRefund.getOrder().getOrderId());
            sysReturnVO.setSourceCode(ecRefund.getOrder().getOrderCode());
            sysReturnVO.setSourceType("or"); // 来源是订单

            sysReturnVO.setReturnStatus(RETURN_STATUS_WAIT_AUTHEN);

            SysOrder order = ecRefund.getOrder();

            sysReturnVO.setCreateTime(now);
            sysReturnVO.setUpdateTime(now);

            sysReturnVO.setHasTaken(YesNoConst.NO);
            
            LogisticsVO lgstInfo = getLgstInfoByName(ecRefund.getLgstName(),ecRefund.getPrjId());// 是否设置物流信息
            
            if(null!=lgstInfo) {
                sysReturnVO.setLgstName(lgstInfo.getLgstName());
                sysReturnVO.setLgstCode(lgstInfo.getLgstCode());
                sysReturnVO.setLgstId(lgstInfo.getLgstId());
                
                sysReturnVO.setLgstNo(ecRefund.getLgstNo());
            }else {
                sysReturnVO.setLgstName(StringUtils.EMPTY);
                sysReturnVO.setLgstCode(StringUtils.EMPTY);
                sysReturnVO.setLgstId(StringUtils.EMPTY);
                
                sysReturnVO.setLgstNo(StringUtils.EMPTY);
            }
            
            Stor relStor = getReturnStorByOrder(order);

            sysReturnVO.setStorId(relStor.getStorId());
            sysReturnVO.setStorCode(relStor.getStorCode());
            sysReturnVO.setStorName(relStor.getStorName());

            ShopVO shop = shopService.findById(ecRefund.getShopId());
            String entId = shop.getEntId();
            sysReturnVO.setEntId(entId);

            // 退货单字段新增 - 开始
            sysReturnVO.setReturnReasonId(sysRefund.getRefundReasonId());   // 将系统退款原因ID写入退货单的退货原因ID
            sysReturnVO.setReturnReasonName(sysRefund.getRefundReasonName());   // 将系统退款原因类型写入退货单的退货原因

            sysReturnVO.setIsCancel(YesNoConst.NO); // 是否取消
            sysReturnVO.setIsAutoCreate(YesNoConst.YES);    // 是否自动创建
            sysReturnVO.setTradeCode(ecRefund.getEcTradeCode());    // 平台交易号
            sysReturnVO.setProvName(order.getProvName());   // 省
            sysReturnVO.setCityName(order.getCityName());   // 市
            sysReturnVO.setDistName(order.getDistName());   // 区
            // 退货单字段新增 - 结束
        }

        return sysReturnVO;
    }

    private LogisticsVO getLgstInfoByName(String lgstName,String prjId) throws Exception {
        LogisticsVO returnValue = null;
        if(StringUtils.isNotEmpty(lgstName)) {
            LogisticsVO lgstParams = new LogisticsVO();
            lgstParams.setLgstName(lgstName);
            lgstParams.setPrjId(prjId);
            List<LogisticsVO> LogisticsVOList = (List<LogisticsVO>)LgstService.getLgstByCondition(lgstParams);
            if(LogisticsVOList.size()>0) {
                returnValue = LogisticsVOList.get(0);
            }
        }
        return returnValue;
    }

    private SysReturn getComposeSysReturn(String orderId) throws Exception {
        SysReturn returnValue = null;
        List<SysReturn> sysReturnList = sysReturnService.selectSysReturnForSysOrder(orderId);
        for(SysReturn sysReturn:sysReturnList){
            if(YesNoConst.YES.equalsIgnoreCase(sysReturn.getIsAutoCreate())
                    &&!YesNoConst.YES.equalsIgnoreCase(sysReturn.getIsCancel())
                    &&!RETURN_FINISH_TYPE_EXCEPTION.equalsIgnoreCase(sysReturn.getFinishType())
                    ){
                // 对于非异常完成的、非取消状态的自动创建的退货单，如果状态是待审核或者待发货，则可以执行退货合并
                if(RETURN_STATUS_WAIT_AUTHEN.equalsIgnoreCase(sysReturn.getReturnStatus())|| RETURN_STATUS_WAIT_RECEIVE_GOODS.equalsIgnoreCase(sysReturn.getReturnStatus())){
                    returnValue = sysReturn;
                    break;
                }
            }
        }
        return returnValue;
    }

    private Stor getReturnStorByOrder(SysOrder order) throws Exception {
        // 如果订单相关仓库没有设置默认退货仓库，就使用订单仓库作为默认退货仓库
        String returnStor = storService.queryReturnStorId(order.getStorId(), order.getShopId(),order.getPrjId());
        
        if(StringUtils.isEmpty(returnStor)) {
            returnStor = order.getStorId();
        }
        
        Stor returnStorObj = storService.selectStorById(returnStor);
        return returnStorObj;
    }

    /**
     * generateReturnGoodsList:根据平台退款单和系统退款单，生成系统退货单明细. <br/>
     *
     * @author zhanghao
     * @param ecRefundVO
     *            平台退款单对象
     * @param sysRefund
     *            系统退款单对象，包含退款单明细信息
     * @param sysReturn
     *            系统退货单对象
     */
    private List<SysReturnSku> generateReturnSkuList(EcRefundVO ecRefundVO, SysRefundVO sysRefund, SysReturn sysReturn,Map<String, Map<String, SysOrderGoods>> orderItemMap) {
        Date now = new Date();
        List<SysReturnSku> returnSkuList = new ArrayList<SysReturnSku>();
        
        Map<String, SysOrderGoods> orderGoodsMap = orderItemMap.get(ecRefundVO.getOrder().getOrderId());
        
        Iterator<String> orderGoodsMapIterator = orderGoodsMap.keySet().iterator();
       
        List<SysRefundSku> sysRefundSkuList = sysRefund.getSysRefundSkuList();
        for (SysRefundSku sysRefundSku : sysRefundSkuList) {
            SysOrderGoods relGoodsSku = orderGoodsMap.get(sysRefundSku.getEcOid());
            SysReturnSku tempReturnSku = new SysReturnSku();
            BeanUtils.copyProperties(sysRefundSku, tempReturnSku);

            tempReturnSku.setReturnSkuId(getUUID());
            tempReturnSku.setReturnId(sysReturn.getReturnId());
            tempReturnSku.setDeleted(YesNoConst.NO);

            tempReturnSku.setCreateTime(now);
            tempReturnSku.setUpdateTime(now);
            
            
            // 退货单明细新增字段——开始
            if(null!=relGoodsSku) {
                tempReturnSku.setQty(relGoodsSku.getQty());
                tempReturnSku.setIsGift(relGoodsSku.getIsGift());  // 是否赠品
                tempReturnSku.setFactUnitPrice(relGoodsSku.getFactUnitPrice());  // 商品实际价格
                tempReturnSku.setDivideGoodsFee(relGoodsSku.getDivideOrderFee());    // 实际支付单价
                tempReturnSku.setSourceSkuId(relGoodsSku.getOrderGoodsId());  // 来源单据商品明细ID（订单商品明细）

                tempReturnSku.setGoodsSkuCost(relGoodsSku.getGoodsSkuCost());
            }else {
                tempReturnSku.setIsGift("n");  // 是否赠品
                tempReturnSku.setFactUnitPrice(new BigDecimal("0"));  // 商品实际价格
                tempReturnSku.setDivideGoodsFee(new BigDecimal("0"));    // 实际支付单价
                tempReturnSku.setGoodsSkuCost(new BigDecimal("0"));    // 实际支付单价
                tempReturnSku.setSourceSkuId("deletedCode");  // 来源单据商品明细ID（订单商品明细）
            }
            tempReturnSku.setRemark(sysRefund.getBuyerRemark());    // 将买家留言加入退货单注释
            tempReturnSku.setIsOrderSku(YesNoConst.YES);
            tempReturnSku.setEcOid(sysRefundSku.getEcOid());
            tempReturnSku.setSourceCode(sysRefund.getOrderCode());

            // 退货单明细新增字段——结束
            
            returnSkuList.add(tempReturnSku);
        }
        
        // 迭代订单商品，将所有赠品添加到退货单商品上
        while(orderGoodsMapIterator.hasNext()) {
            SysOrderGoods orderGoods = orderGoodsMap.get(orderGoodsMapIterator.next());
            if(YesNoConst.YES.equalsIgnoreCase(orderGoods.getIsGift())) {
                SysReturnSku tempReturnSku = new SysReturnSku();
                BeanUtils.copyProperties(orderGoods, tempReturnSku);
                
                tempReturnSku.setReturnSkuId(getUUID());
                tempReturnSku.setReturnId(sysReturn.getReturnId());
                tempReturnSku.setDeleted(YesNoConst.NO);
                
                tempReturnSku.setCreateTime(now);
                tempReturnSku.setUpdateTime(now);
                
                // 退货单明细新增字段——开始
                tempReturnSku.setRemark(sysRefund.getBuyerRemark());    // 将买家留言加入退货单注释
                tempReturnSku.setIsGift(orderGoods.getIsGift());  // 是否赠品
                tempReturnSku.setIsOrderSku(YesNoConst.YES);
                tempReturnSku.setFactUnitPrice(orderGoods.getFactUnitPrice());  // 商品实际价格
                tempReturnSku.setDivideGoodsFee(orderGoods.getDivideOrderFee());    // 实际支付单价
                tempReturnSku.setSourceSkuId(orderGoods.getOrderGoodsId());  // 来源单据商品明细ID（订单商品明细）
                tempReturnSku.setEcOid(orderGoods.getOid());
                tempReturnSku.setSourceCode(sysRefund.getOrderCode());
                // 退货单明细新增字段——结束
                
                returnSkuList.add(tempReturnSku);
            }
        }
        
        
        return returnSkuList;
    }

    /**
     * generateSysRefundGoodsListFromEcRefund:根据平台退款单获取系统退款单明细. <br/>
     *
     * @author zhanghao
     * @param ecRefund
     * @param orderItemMap
     * @return
     * @throws Exception
     */
    private List<SysRefundSku> generateSysRefundSkuListFromEcRefund(EcRefundVO ecRefund, SysRefund sysRefund,
            Map<String, Map<String, SysOrderGoods>> orderItemMap) throws Exception {
        List<EcRefundItem> ecRefundItemList = new ArrayList<EcRefundItem>();
        List<SysRefundSku> sysRefundGoodsList = new ArrayList<SysRefundSku>();

        BigDecimal totalFefundFee = ecRefund.getRefundFee();

        try {
            ecRefundItemList = taobaoRefundItemService.getByecRefundId(ecRefund.getEcRefundId());
            for (EcRefundItem ecRefundItem : ecRefundItemList) {

                SysOrderGoods orderSkuObj = orderItemMap.get(ecRefund.getOrder().getOrderId()).get(ecRefundItem.getEcOid());

                SysRefundSku sysRefundSku = new SysRefundSku();
                BeanUtils.copyProperties(ecRefundItem, sysRefundSku);

                sysRefundSku.setRefundId(sysRefund.getRefundId());
                sysRefundSku.setDeleted("n");
                sysRefundSku.setCreateTime(sysRefund.getCreateTime());
                sysRefundSku.setUpdateTime(sysRefund.getCreateTime());

                // 判断这个退款商品是否组合商品，如果是组合商品，则需要添加组合商品拆分后的订单商品
                boolean isGroupGoods = orderSkuObj.getComposeGoodsFlag()>0?true:false;

                if(isGroupGoods){
                    // 如果是组合商品，就把组合商品都加进来
                    // 查询订单上的组合商品
                    Map tempQueryMap = new HashMap();
                    List orderIdList = new ArrayList<String>();
                    orderIdList.add(ecRefund.getOrder().getOrderId());
                    tempQueryMap.put("order_id", orderIdList);
                    tempQueryMap.put("oId", orderSkuObj.getOid());

                    List<SysOrderGoods> sysOrderGoodsList = sysOrderDAO.selectSysOrderGoodsList(tempQueryMap);

                    BigDecimal total = new BigDecimal(0);   // 缓存组合商品的总金额

                    for(SysOrderGoods SysOrderGoods : sysOrderGoodsList){
                        total = total.add(SysOrderGoods.getDivideOrderFee());
                    }

                    for(SysOrderGoods SysOrderGoods : sysOrderGoodsList){
                        if(StringUtils.isNotEmpty(SysOrderGoods.getSkuId())){
                            SysRefundSku sysRefundSkuTemp = new SysRefundSku();
                            BeanUtils.copyProperties(sysRefundSku,sysRefundSkuTemp);

                            sysRefundSkuTemp.setGoodsCode(SysOrderGoods.getGoodsCode());
                            sysRefundSkuTemp.setGoodsId(SysOrderGoods.getGoodsId());
                            sysRefundSkuTemp.setGoodsName(SysOrderGoods.getGoodsName());

                            sysRefundSkuTemp.setSourceSkuId(SysOrderGoods.getOrderGoodsId());

                            sysRefundSkuTemp.setSkuCode(SysOrderGoods.getSkuCode());
                            sysRefundSkuTemp.setSkuId(SysOrderGoods.getSkuId());
                            sysRefundSkuTemp.setSkuName(SysOrderGoods.getSkuName());

                            sysRefundSkuTemp.setRefundSkuId(getUUID());

                            // 获取计算比例
                            BigDecimal percent = SysOrderGoods.getDivideOrderFee().divide(total, 2, BigDecimal.ROUND_HALF_UP);


                            sysRefundSkuTemp.setRefundFee(totalFefundFee.multiply(percent));    // 设置退款金额

                            // 如果只有1个规格，就将商品名称赋值给规格名称
                            if(StringUtils.isEmpty(sysRefundSkuTemp.getEcSkuName())&&StringUtils.isNotEmpty(sysRefundSkuTemp.getEcItemName())){
                                sysRefundSkuTemp.setEcSkuName(sysRefundSkuTemp.getEcItemName());
                            }

                            sysRefundGoodsList.add(sysRefundSkuTemp);
                        }
                    }

                }else{
                    // 如果不是组合商品，则直接添加商品

                    // 如果商品只有1个规格，就将商品名称赋值给规格名称
                    if(StringUtils.isEmpty(sysRefundSku.getEcSkuName())&&StringUtils.isNotEmpty(sysRefundSku.getEcItemName())){
                        sysRefundSku.setEcSkuName(sysRefundSku.getEcItemName());
                    }

                    //if (null != orderSkuObj&&StringUtils.isNotEmpty(orderSkuObj.getSkuId())) {
                        sysRefundSku.setRefundSkuId(getUUID());
                        sysRefundSku.setGoodsCode(orderSkuObj.getGoodsCode());
                        sysRefundSku.setGoodsId(orderSkuObj.getGoodsId());
                        sysRefundSku.setGoodsName(orderSkuObj.getGoodsName());

                        sysRefundSku.setSourceSkuId(orderSkuObj.getOrderGoodsId());

                        sysRefundSku.setSkuCode(orderSkuObj.getSkuCode());
                        sysRefundSku.setSkuId(orderSkuObj.getSkuId());
                        sysRefundSku.setSkuName(orderSkuObj.getSkuName());
                        sysRefundGoodsList.add(sysRefundSku);
                    //}
                }
                logger.debug(String.format("\t\t根据平台退款单明细[规格:%s]生成系统退款单明细[规格:%s]成功", ecRefundItem.getEcSkuCode(), sysRefundSku.getSkuCode()));
            }
        } catch (Exception e) {
            logger.error(String.format("获取平台退款单(单号：%s)明细失败...", ecRefund.getEcRefundCode()));
            throw e;
        }
        return sysRefundGoodsList;
    }

    /**
     * getEcRefundListToLoad:查询当前时间点上的需要下载的平台退款单列表. <br/>
     *
     * @return
     * @author zhanghao
     */
    private List<EcRefundVO> getEcRefundListToLoad(String shopId, String ecRefundCode, String customerId) {
        List<EcRefundVO> returnValue = new ArrayList<EcRefundVO>();
        EcRefundVO ecRefundVO = new EcRefundVO();
        ecRefundVO.setShopId(shopId);
        if (StringUtils.isNotEmpty(ecRefundCode)) {
            ecRefundVO.setEcRefundCode(ecRefundCode);
        } else if (StringUtils.isNotEmpty(customerId)) {
            ecRefundVO.setBuyerNick(customerId);
        }
        // 获取查询开始时间，申请退款时间晚于该时间的平台退库单将被查询出来
        Date queryStartDate = getShopEcRefundQueryStartDate(shopId);
        ecRefundVO.setQueryStartDate(queryStartDate);
        try {
            returnValue = taobaoRefundService.getEcRefund4AutoDownload(ecRefundVO);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return returnValue;
    }
    
    /**
     * getEcRefundListToLoad:查询当前时间点上的需要下载的平台退款单列表. <br/>
     *
     * @return
     * @author zhanghao
     */
    private List<EcRefundVO> getEcRefundListToLoadByOrder(String shopId, String ecTradeCode) {
        List<EcRefundVO> returnValue = new ArrayList<EcRefundVO>();
        EcRefundVO ecRefundVO = new EcRefundVO();
        ecRefundVO.setShopId(shopId);
        ecRefundVO.setEcTradeCode(ecTradeCode);
        // 获取查询开始时间，申请退款时间晚于该时间的平台退库单将被查询出来
        Date queryStartDate = getShopEcRefundQueryStartDate(shopId);
        ecRefundVO.setQueryStartDate(queryStartDate);
        try {
            returnValue = taobaoRefundService.getEcRefund4AutoDownload(ecRefundVO);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return returnValue;
    }

    /**
     * getEcRefundListToLoad:查询当前时间点上的需要下载的平台退款单列表. <br/>
     *
     * @return
     * @author zhanghao
     */
    private List<EcRefundVO> getEcRefundListToUpdate(String shopId, String ecRefundCode, String customerId) {
        List<EcRefundVO> returnValue = new ArrayList<EcRefundVO>();
        EcRefundVO ecRefundVO = new EcRefundVO();
        ecRefundVO.setShopId(shopId);
        if (StringUtils.isNotEmpty(ecRefundCode)) {
            ecRefundVO.setEcRefundCode(ecRefundCode);
        } else if (StringUtils.isNotEmpty(customerId)) {
            ecRefundVO.setBuyerNick(customerId);
        }
        // 获取查询开始时间，申请退款时间晚于该时间的平台退库单将被查询出来
        Date queryStartDate = getShopEcRefundQueryStartDate(shopId);
        ecRefundVO.setQueryStartDate(queryStartDate);
        try {
            returnValue = taobaoRefundService.getEcRefund4AutoDownload(ecRefundVO);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return returnValue;
    }

    /**
     * getShopEcRefundQueryStartDate:获取店铺设置的平台退款单检索开始时间. <br/>
     * 如果店铺设置了该时间，就取得时间.<br/>
     * 如果店铺未设置该时间，就取店铺的创建时间.<br/>
     *
     * @author zhanghao
     * @param shopId
     * @return
     */
    private Date getShopEcRefundQueryStartDate(String shopId) {
        ShopVO shop = AbstractAdapterFactory.getShop(shopId);
        Date queryDate = null;
        if(shop!=null){
            queryDate = shop.getCreateTime();

        }else{
            queryDate = DateUtils.getDate(2016, "MAR", 1);

        }
        return queryDate;
    }

    /**
     * getUUID:主键生成方法. <br/>
     *
     * @author zhanghao
     * @return
     */
    private String getUUID() {
        String uuid = java.util.UUID.randomUUID().toString().replaceAll("-", StringUtils.EMPTY);
        return uuid;
    }

    /**
     * generateSysRefundFromEcRefund:从平台退款单生成系统退款单. <br/>
     * 系统退款单默认状态为处理中.<br/>
     *
     * @author zhanghao
     * @param ecRefund
     * @return
     * @throws Exception
     */
    private SysRefundVO generateSysRefundFromEcRefund(EcRefundVO ecRefund) throws Exception {
        SysRefundVO record = new SysRefundVO();
        BeanUtils.copyProperties(ecRefund, record);

        String refundCode = generateRefundCode(ecRefund.getShopId());

        String sysRefundId = getUUID();
        Date now = new Date();
        record.setRefundId(sysRefundId);
        record.setRefundCode(refundCode);
        record.setDeleted(YesNoConst.NO);
        record.setCreateTime(now);
        record.setUpdateTime(now);
        
        record.setRefundStatus(getRefundStatusFromEcRefundStatus(ecRefund));

        record.setBuyerRemark(ecRefund.getRefundDesc());
        record.setEntId(ecRefund.getOrder().getEntId());
        record.setOrderId(ecRefund.getOrder().getOrderId());
        record.setRefundReason(ecRefund.getRefundReason());
        
        // 修正，对应数据库变更20171023：oms_refund表增加 order_code 订单编号 is_auto_create自动创建标志
        record.setOrderCode(ecRefund.getOrder().getOrderCode());
        record.setIsAutoCreate(YesNoConst.YES);

        if (StringUtils.isNotEmpty(ecRefund.getRefundReason())) {
            try {
                RdfundReasonType refundReasonType = getRefundReasonByEcRefundReason(ecRefund.getRefundReason());
                record.setRefundReasonId(refundReasonType.getRefundReasonId());
                record.setRefundReasonName(refundReasonType.getRefundReasonName());
            } catch (Exception e) {
                logger.debug("未找到平台退款原因相关的系统退款原因,退款编号和name将留空");
                record.setRefundReasonId("");
                record.setRefundReasonName("");
            }
        } else {
            record.setRefundReasonId(ecRefund.getRefundReason());
            record.setRefundReasonName(ecRefund.getRefundReason());
        }
        record.setEcRefundStatus(ecRefund.getRefundStatus());

        updateRefundInfoByStatus(record,ecRefund,StringUtils.EMPTY);

        return record;
    }

    /**
     * getRefundStatusFromEcRefundStatus:将平台退款单状态转换成系统退款单状态. <br/>
     *
     * @author zhanghao
     * @param lastEcRefund
     * @return
     */
    private String getRefundStatusFromEcRefundStatus(EcRefund lastEcRefund) {
        String returnString = SysRefundStatusConsts.REGISTER;
        String ecRefundStatus = lastEcRefund.getRefundStatus();
        if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_WAIT_SELLER_AGREE)){
            if(YesNoConst.YES.equalsIgnoreCase(lastEcRefund.getHasGoodReturn())) {
                returnString = SysRefundStatusConsts.REFUND_APPLIED;
            }else {
                returnString = SysRefundStatusConsts.REGISTER;
            }
        }else if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_WAIT_BUYER_RETURN_GOODS)) {
            returnString = SysRefundStatusConsts.WAIT_BUYER_OPER;
        }else if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_WAIT_SELLER_CONFIRM_GOODS)) {
            returnString = SysRefundStatusConsts.REGISTER;
        }else if(ecRefundStatus.equalsIgnoreCase(ECRefundStatusConsts.EC_SUCCESS)){
            returnString = SysRefundStatusConsts.REFUNDED;
        }else{
            returnString = SysRefundStatusConsts.CLOSED;
        }
           
        return returnString;
    }

    /**
     * getRefundReasonByEcRefundReason:根据平台退款单的原因描述获取系统退款单信息 <br/>
     *
     * @author zhanghao
     * @param ecRefundReason
     * @return
     * @throws Exception
     */
    private RdfundReasonType getRefundReasonByEcRefundReason(String ecRefundReason) throws Exception {
        return refundReasonTypeService.getRdfundReasonTypeInfoWithEcRefundReason(ecRefundReason);
    }

    /**
     * isAutoGenerateReturn:判断自动生成退货单的系统开关是否开启. <br/>
     *
     * @author zhanghao
     * @return
     */
    private boolean isAutoGenerateReturn(String shopId) {
        boolean returnValue = false;
        ShopVO shop = AbstractAdapterFactory.getShop(shopId);
        if (YesNoConst.YES.equals(shop.getIsAutoGenerateReturn())) {
            returnValue = true;
        } else {
            returnValue = false;
        }
        return returnValue;
    }

    /**
     * hasUnConnectedGoods:判断系统退款明细中是否包含未关联的系统商品. <br/>
     *
     * @author zhanghao
     * @param sysRefundSkuList
     * @return
     */
    private boolean hasUnConnectedGoods(List<SysRefundSku> sysRefundSkuList) {
        boolean returnValue = false;
        for (SysRefundSku sysRefundSku : sysRefundSkuList) {
            if (StringUtils.isEmpty(sysRefundSku.getSkuCode()) || StringUtils.isEmpty(sysRefundSku.getGoodsCode())) {
                returnValue = true;
                break;
            }
        }
        return returnValue;
    }

    /**
     * hasGenerateReturn:判断是否需要生成退货单. <br/>
     * 
     * - 平台退款单包含退货标识
     * 
     * - 且自动生成退货单开关开启
     * 
     * - 且退款单明细不存在未关联的系统商品
     * 
     * 则生成退货单
     *
     *
     * @author zhanghao
     * @param ecRefundVO
     * @param sysRefund
     * @param orderItemMap 
     * @return
     */
    private boolean hasGenerateReturn(EcRefundVO ecRefundVO, SysRefundVO sysRefund, Map<String, Map<String, SysOrderGoods>> orderItemMap) {
        boolean statusCorrect = ECRefundStatusConsts.EC_WAIT_SELLER_AGREE.equalsIgnoreCase(sysRefund.getEcRefundStatus())
                ||ECRefundStatusConsts.EC_WAIT_BUYER_RETURN_GOODS.equalsIgnoreCase(sysRefund.getEcRefundStatus())
                ||ECRefundStatusConsts.EC_WAIT_SELLER_CONFIRM_GOODS.equalsIgnoreCase(sysRefund.getEcRefundStatus());

        // 退款单有退货诉求，退款单状态对应，且退款单明细不存在未关联系统商品的订单商品
        boolean allowReturn = YesNoConst.YES.equalsIgnoreCase(ecRefundVO.getHasGoodReturn())
                && !hasUnConnectedGoods(sysRefund.getSysRefundSkuList())
                && !hasUnDeletedGoods(sysRefund.getSysRefundSkuList(),sysRefund.getOrderId(),orderItemMap)
                && statusCorrect;
        return allowReturn;
    }

    /**
     * hasUnDeletedGoods:判断退款商品是否包含在订单上已删除商品. <br/>
     *
     * @author zhanghao
     * @param sysRefundSkuList
     * @param string 
     * @param orderItemMap
     * @return
     */
    private boolean hasUnDeletedGoods(List<SysRefundSku> sysRefundSkuList, String orderId, Map<String, Map<String, SysOrderGoods>> orderItemMap) {
        boolean returnValue = false;
        Map<String, SysOrderGoods> orderItems = orderItemMap.get(orderId);
        SysOrderGoods ordergoodsTemp = null;
        for (SysRefundSku sysRefundSku : sysRefundSkuList) {
            String oid = sysRefundSku.getEcOid();
            if(StringUtils.isEmpty(oid)) {
                String skuCode = sysRefundSku.getSkuCode();
                ordergoodsTemp= orderItems.get(skuCode);
            }else {
                ordergoodsTemp= orderItems.get(oid);
            }
            if(ordergoodsTemp!=null&&YesNoConst.YES.equals(ordergoodsTemp.getDeleted())) {
                return true;
            }
        }
        return returnValue;
    }

    /**
     * generateRefundCode:根据店铺ID生成系统退款单编码. <br/>
     *
     * @author zhanghao
     * @param shopId
     * @return
     * @throws Exception
     */
    private String generateRefundCode(String shopId) throws Exception {
        return generateReturnCodeWithType("RF", shopId);
    }

    /**
     * generateRefundCode:根据店铺ID生成退货单编码. <br/>
     *
     * @author zhanghao
     * @param shopId
     * @return
     * @throws Exception
     */
    private String generateReturnCode(String shopId) throws Exception {
        return generateReturnCodeWithType("RT", shopId);
    }

    /**
     * generateReturnCodeWithType:编码生成方法 <br/>
     *
     * @author zhanghao
     * @param codeType
     *            编码类型
     * @param shopId
     *            店铺ID
     * @return
     * @throws Exception
     */
    private String generateReturnCodeWithType(String codeType, String shopId) throws Exception {
        ShopVO shop = shopService.findById(shopId);
        ProjectVO project = AbstractAdapterFactory.getProject(shop.getPrjId());
        String prjShortName = project.getPrjShortName();
        String returnCode = codeType + prjShortName + CodeUtil.getCode();
        return returnCode;
    }

    /**
     * 按条件获取系统退款单列表.
     *
     * @throws Exception
     */
    @Override
    public List<SysRefundVO> getSysRefundListByCondition(SysRefundVO sysRefundVO) throws Exception {
        return sysRefundDAO.selectSysRefundListByCondition(sysRefundVO);
    }

    /**
     * getSuccessMap:获取成功消息Map. <br/>
     *
     * @author zhanghao
     * @param message
     * @return
     * @since JDK 1.6
     */
    private Map<String, Object> getSuccessMap(String message) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        returnMap.put("result", "success");
        returnMap.put("msg", message);
        return returnMap;
    };

    /**
     * getFailedMap:获取失败消息Map. <br/>
     *
     * @author zhanghao
     * @param message
     * @return
     * @since JDK 1.6
     */
    private Map<String, Object> getFailedMap(String message) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        returnMap.put("result", "failed");
        returnMap.put("msg", message);
        return returnMap;
    }

    @Override
    public Map<String,Object> downloadEcRefundByOrderCode(String shopId, String orderCode, boolean isFetching) {
        Map<String, Object> returnMap = new HashMap<String,Object>();
        try {
            if(isFetching){
                // 根据平台交易号下载时，不下载平台退款单
            }
            // 2. 获取可下载的系统退款单
            List<EcRefundVO> ecRefundVOList = getEcRefundListToLoadByOrder(shopId, orderCode);
            if (ecRefundVOList.size() > 0) {
                logger.debug("订单[订单号：" + orderCode + "]开始执行平台退款单进系统...");
                downloadSysRefund(shopId, ecRefundVOList);
                logger.debug("订单[订单号：" + orderCode + "]执行平台退款单进系统完成");
            }
            // 3. 执行更新退款单任务
            logger.debug("订单[订单号：" + orderCode + "]执行平台退款单进系统完成");
            updateEcRefund(shopId, "","");
            logger.debug("订单[订单号：" + orderCode + "]执行平台退款单更新完成");
            returnMap = getSuccessMap("平台退款单进系统成功");
        }catch(Exception e) {
            logger.error("根据平台交易号执行退款单进系统失败，请联系系统管理员",e);
            returnMap = getFailedMap("平台退款单进系统失败，请联系系统管理员");
        }

        return returnMap;
        
    };
    
    private String[] getNullPropertyNames (Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
}
